package com.feshfans.xmpp;

import com.feshfans.xmpp.client.RosterClient;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smack.roster.*;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
import org.jivesoftware.smack.util.StringUtils;
import org.jxmpp.jid.BareJid;
import org.jxmpp.jid.FullJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.stringprep.XmppStringprepException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collection;

public class XmppConnectionManager {

    private static final Logger Log = LoggerFactory.getLogger(XmppConnectionManager.class);

    private static XMPPTCPConnection connection;

    private XmppConnectionManager(){

    }

    public static synchronized void create(String host, int port, String xmppDomain){

        if(connection!=null){
            return ;
        }

        XMPPTCPConnectionConfiguration config = null;
        try {
            config = XMPPTCPConnectionConfiguration.builder()
                    .setXmppDomain(xmppDomain)
                    .setPort(port)
                    .setSecurityMode(ConnectionConfiguration.SecurityMode.disabled)
                    .setConnectTimeout(10*1000)
                    .setHost(host)
                    .build();
        } catch (XmppStringprepException e) {
            Log.error("创建 Connection Config error,host:{},port:{},xmppDomain:{}",host,port,xmppDomain,e);
        }

        connection = new XMPPTCPConnection(config);
        connection.addConnectionListener(new MyConnectionListener());
        connection.addAsyncStanzaListener(new MyStazaListener(),new MyStanzaFilter());

        try {
            connection.connect();
        } catch (Exception e) {
            Log.error("连接 xmpp server error.",e);
        }

    }


    public static XMPPTCPConnection acquire(){
        if(connection==null){
            throw new RuntimeException("连接还未创建，请先调用 create 方法进行创建");
        }
        return connection;
    }

    public static void shutdownNow(){
        if(connection!=null){
            connection.instantShutdown();
        }
    }

    static class MyConnectionListener implements ConnectionListener{

        @Override
        public void connected(XMPPConnection connection) {
            System.out.println("连接成功");
        }

        @Override
        public void authenticated(XMPPConnection connection, boolean resumed) {
            System.out.println("认证成功");
        }

        @Override
        public void connectionClosed() {
            System.out.println("连接关闭");
        }

        @Override
        public void connectionClosedOnError(Exception e) {
            System.out.println("关闭连接时发生错误");
            e.printStackTrace();
        }

        @Override
        public void reconnectionSuccessful() {

        }

        @Override
        public void reconnectingIn(int seconds) {

        }

        @Override
        public void reconnectionFailed(Exception e) {

        }
    }

    static class MyStazaListener implements StanzaListener{

        @Override
        public void processStanza(Stanza packet) throws SmackException.NotConnectedException, InterruptedException, SmackException.NotLoggedInException {

            Log.debug("packet : {}",packet.toXML());

            if(packet instanceof Message){
                Message message = (Message)packet;
                Message.Type type = message.getType();
                if(type == Message.Type.chat){
                    Jid fromJid = message.getFrom();
                    String body = message.getBody();
                    ExtensionElement extensionElement =  message.getExtension("http://jabber.org/protocol/chatstates");
                    if(extensionElement!=null){
                        String elementName = extensionElement.getElementName();
                        System.out.println("name : "+elementName);
                    }
                    if(StringUtils.isNotEmpty(body)){
                        System.out.println("收到了来自 "+fromJid.getLocalpartOrNull().toString()+" 的消息 : "+body);
                    }
                }
                if(type == Message.Type.groupchat){

                }

            }

            if(packet instanceof Presence){
                Presence presence = (Presence) packet;
                String status = presence.getStatus();
                Jid fromJid = presence.getFrom();
                if(StringUtils.isNotEmpty(status)){
                    System.out.println("好友 "+fromJid.getLocalpartOrNull().toString()+" "+status);
                }

            }

            if(packet instanceof IQ){

                /*System.out.println("xml : \r\n"+packet.toXML());

                IQ iq = (IQ)packet;
                PublishItem pe = iq.getExtension("query","jabber:iq:roster");
                System.out.println(iq.getLanguage());
                System.out.println(iq.getType().toString());
                System.out.println(iq.getStanzaId());
                XmlStringBuilder builder = iq.getChildElementXML();

                System.out.println(builder.toString());*/

                /*ExtensionElement extensionElement = iq.getExtension("jabber:iq:roster");
                if(extensionElement != null){
                    XmlStringBuilder xmlStringBuilder = iq.getChildElementXML();
                    System.out.println(xmlStringBuilder.toString());
                }*/
            }

        }
    }

    static class MyStanzaFilter implements StanzaFilter{

        @Override
        public boolean accept(Stanza stanza) {

            return true;
        }
    }

}
